home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / MacCleo / geoface / main0.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  14.5 KB  |  572 lines

  1. /* aux2glut conversion Copyright (c) Mark J. Kilgard, 1997 */
  2.  
  3. /* ==========================================================================
  4.                                MAIN_C
  5. =============================================================================
  6.  
  7.     FUNCTION NAMES
  8.  
  9.     movelight         -- moves the light source.
  10.     rotatexface     -- rotates the face about the X axis.
  11.     rotateyface     -- rotates the face about the Y axis.
  12.     myinit         -- local initialization.
  13.     faceinit         -- glutInit(&argc, argv); initialize the face data.
  14.     display         -- display functions.
  15.     myReshape         -- window respahe callback.
  16.     error_exit        -- error function.
  17.     usage        -- usage function.
  18.     GLenum Key         -- keyboard mappings.
  19.     main         -- main program.
  20.  
  21.  
  22.     C SPECIFICATIONS
  23.  
  24.     void movelight     ( int x, int y )
  25.     void rotatexface     ( int x, int y )
  26.     void rotateyface     ( int x, int y )
  27.     void myinit     ( void )
  28.     faceinit         ( void )
  29.     void display     ( void )
  30.     void myReshape     ( GLsizei w, GLsizei h )
  31.     void error_exit    ( char *error_message )
  32.     void usage        ( char *name )
  33.     static GLenum Key     ( int key, GLenum mask )
  34.     void main         ( int argc, char** argv )
  35.  
  36.     DESCRIPTION
  37.     
  38.     This module is where everything starts.    This module comes as is 
  39.     with no warranties.  
  40.  
  41.     SIDE EFFECTS
  42.     Unknown.
  43.    
  44.     HISTORY
  45.     Created 16-Dec-94  Keith Waters at DEC's Cambridge Research Lab.
  46.     Modified 22-Nov-96 Sing Bing Kang (sbk@crl.dec.com)
  47.       Added function print_mesg to print out all the keyboard commands
  48.       Added the following functionalities:
  49.         rereading the expression file
  50.         changing the expression (based on the expression file)
  51.         quitting the program with 'q' or 'Q' in addition to 'Esc'
  52.  
  53. ============================================================================ */
  54.  
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <stdlib.h>
  58. #include <GLUT/glut.h>
  59.  
  60. #include "memory.h"               /* Local memory allocation macros          */
  61. /*#include "window.h"                Local window header                     */
  62. #include "head.h"                 /* Local head data structure               */
  63.  
  64. int verbose = 0;
  65.  
  66. void print_mesg(void);
  67.  
  68. int DRAW_MODE = 2 ;
  69.  
  70. HEAD *face ;
  71.  
  72. static int spinxlight = 0 ;
  73. static int spinylight = 0 ;
  74. static int spinxface = 0 ;
  75. static int spinyface = 0 ;
  76.  
  77.  
  78. /* ========================================================================= */
  79. /* motion                                                                 */
  80. /* ========================================================================= */  
  81. /*
  82. ** Rotate the face and light about.
  83. */
  84.  
  85. int rotate = 0, movelight = 0, origx, origy;
  86.  
  87. void motion ( int x, int y )
  88. {
  89.   if (rotate) {
  90.     spinyface = ( spinyface + (x - origx) ) % 360 ;
  91.     spinxface = ( spinxface + (y - origy) ) % 360 ;
  92.     origx = x;
  93.     origy = y;
  94.     glutPostRedisplay();
  95.   }
  96.   if (movelight) {
  97.     spinylight = ( spinylight + (x - origx ) ) % 360 ;
  98.     spinxlight = ( spinxlight + (y - origy ) ) % 360 ;
  99.     origx = x;
  100.     origy = y;
  101.     glutPostRedisplay();
  102.   }
  103. }
  104.  
  105. void
  106. mouse(int button, int state, int x, int y)
  107. {
  108.   switch(button) {
  109.   case GLUT_LEFT_BUTTON:
  110.     if (state == GLUT_DOWN) {
  111.       origx = x;
  112.       origy = y;
  113.       rotate = 1;
  114.     } else {
  115.       rotate = 0;
  116.     }
  117.     break;
  118.   case GLUT_MIDDLE_BUTTON:
  119.     if (state == GLUT_DOWN) {
  120.       origx = x;
  121.       origy = y;
  122.       movelight = 1;
  123.     } else {
  124.       movelight = 0;
  125.     }
  126.     break;
  127.   }
  128. }
  129.  
  130.  
  131. /* ========================================================================= */
  132. /* myinit                                                             */
  133. /* ========================================================================= */  
  134. /*
  135. ** Do the lighting thing.
  136. */
  137.  
  138. void myinit ( void )
  139. {
  140.   glEnable    ( GL_LIGHTING   ) ;
  141.   glEnable    ( GL_LIGHT0     ) ;
  142.   glDepthFunc ( GL_LEQUAL     ) ;
  143.   glEnable    ( GL_DEPTH_TEST ) ;
  144. }
  145.  
  146.  
  147. /* ========================================================================= */
  148. /* faceinit                                                             */
  149. /* ========================================================================= */  
  150. /*
  151. ** Read in the datafiles and glutInit(&argc, argv); initialize the face data structures.
  152. */
  153.  
  154. void
  155. faceinit ( void )
  156. {
  157.   face = create_face         ( "index.dat", "faceline.dat") ;
  158.   read_muscles               ("muscle.dat", face ) ;
  159.   read_expression_vectors    ("expression-vectors.dat", face ) ;
  160.   data_struct                ( face ) ;    
  161. }
  162.  
  163. void
  164. read_expressions(void)
  165. {
  166.   read_expression_vectors    ("expression-vectors.dat", face ) ;
  167. }
  168.  
  169. /* ========================================================================= */
  170. /* display                                                                   */
  171. /* ========================================================================= */  
  172. /*
  173. ** Here's were all the display action takes place.
  174. */
  175.  
  176. void display ( void )
  177. {
  178.   GLfloat position [] = { 30.0, 70.0, 100.0, 1.0 }  ;
  179.     
  180.   glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
  181.  
  182.   glPushMatrix ( ) ; 
  183.   
  184.     glTranslatef ( 0.0, 0.0, -30.0 ) ;
  185.  
  186.     glRotated    ( (GLdouble) spinxface, 1.0, 0.0, 0.0 ) ;
  187.     glRotated    ( (GLdouble) spinyface, 0.0, 1.0, 0.0 ) ;
  188.   
  189.     glPushMatrix ( ) ; 
  190.       glRotated        ( (GLdouble) spinxlight, 1.0, 0.0, 0.0 ) ;
  191.       glRotated        ( (GLdouble) spinylight, 0.0, 1.0, 0.0 ) ;
  192.       glLightfv        ( GL_LIGHT0, GL_POSITION, position ) ;
  193.   
  194.       glTranslated     ( 0.0, 0.0, 50.0 ) ;
  195.       glDisable        ( GL_LIGHTING ) ;
  196.       glColor3f        ( 0.0, 1.0, 1.0 ) ;
  197.       glutWireCube     ( 0.1 ) ;
  198.       glEnable        ( GL_LIGHTING ) ;
  199.    glPopMatrix ( ) ;
  200.  
  201.   calculate_polygon_vertex_normal     ( face ) ;
  202.  
  203.   paint_polygons             ( face, DRAW_MODE, 0 ) ;    
  204.  
  205.   if ( DRAW_MODE == 0 )
  206.     paint_muscles            ( face ) ;
  207.   
  208.   glPopMatrix();
  209.  
  210.   glutSwapBuffers();
  211. }
  212.  
  213.  
  214. /* ========================================================================= */
  215. /* myReshape                                                             */
  216. /* ========================================================================= */  
  217. /*
  218. ** What to do of the window is modified.
  219. */
  220.  
  221. void myReshape ( GLsizei w, GLsizei h )
  222. {
  223.   glViewport    ( 0,0,w,h ) ;
  224.   glMatrixMode  ( GL_PROJECTION ) ;
  225.   glLoadIdentity( ) ;
  226.   gluPerspective( 40.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0 ) ;
  227.   glMatrixMode  ( GL_MODELVIEW ) ;
  228. }
  229.  
  230.  
  231. /* ========================================================================= */
  232. /* error_exit                                                                 */
  233. /* ========================================================================= */  
  234. /*
  235. ** Problems!
  236. */
  237.  
  238. void error_exit( char *error_message )
  239. {
  240.     fprintf ( stderr, "%s\n", error_message ) ;
  241.     exit( 1 ) ;
  242. }
  243.  
  244.  
  245. /* ========================================================================= */
  246. /* usage                                                             */
  247. /* ========================================================================= */  
  248. /*
  249. ** At startup provide usage modes.
  250. */
  251.  
  252. void usage( char *name )
  253. {
  254.     fprintf( stderr, "\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
  255.         "usage: ", name, " [options]\n\n",
  256.         "  Options:\n",
  257.         "    -display  displayname  specify an X server connection\n",
  258.         "    -geometry geometry     specify window geometry in pixels\n",
  259.         "    -rgba                  ask for rgba visual\n",
  260.         "    -index                 ask for color index visual\n",
  261.         "    -doublebuffer          ask for double buffered visual\n",
  262.         "    -singlebuffer          ask for single buffered visual\n",
  263.         "    -accum                 ask for accumulation buffer\n",
  264.         "    -alpha                 ask for alpha buffer\n",
  265.         "    -depth                 ask for depth buffer\n",
  266.         "    -stencil               ask for stencil buffer\n",
  267.         "    -aux nauxbuf           specify number of aux buffers\n",
  268.         "    -level planes          specify planes (0=main,>0=overlay,<0=underlay\n",
  269.         "    -transparent           ask for transparent overlay\n",
  270.         "    -opaque                ask for opaque overlay\n"
  271.     );
  272.     
  273.     exit( 1);
  274. }
  275.  
  276. /* ========================================================================= */
  277. /* Key                                                                 */
  278. /* ========================================================================= */
  279. /*
  280. ** Actions on a key press.
  281. */
  282.  
  283. static int m = 0, e = 0;
  284.  
  285. /* ARGSUSED1 */
  286. static void Key ( unsigned char key, int x, int y )
  287. {
  288.   char title[512];
  289.   
  290.     switch ( key ) {
  291.       case 27 :
  292.       case 'q' :
  293.       case 'Q' :
  294.     exit (0) ;
  295.  
  296.       case 'r' :
  297.       case 'R' :
  298.     printf ("Rereading expression file\n");
  299.         read_expressions();
  300.     e = 0; /* reset the expression count variable */
  301.     glutPostRedisplay();
  302.     break;
  303.  
  304.       case 'a' :
  305.     printf ("increment muscle: %s\n", face->muscle[m]->name ) ;
  306.  
  307.     /* set the muscle activation */
  308.     face->muscle[m]->mstat += 0.1 ;
  309.     
  310.     activate_muscle ( face, 
  311.              face->muscle[m]->head, 
  312.              face->muscle[m]->tail, 
  313.              face->muscle[m]->fs,
  314.              face->muscle[m]->fe,
  315.              face->muscle[m]->zone,
  316.              0.1 ) ;
  317.     glutPostRedisplay();
  318.     break;
  319.  
  320.       case 'A' :
  321.     printf ("decrement muscle: %s\n", face->muscle[m]->name ) ;
  322.     face->muscle[m]->mstat -= 0.1 ;
  323.  
  324.     activate_muscle ( face, 
  325.              face->muscle[m]->head, 
  326.              face->muscle[m]->tail, 
  327.              face->muscle[m]->fs,
  328.              face->muscle[m]->fe,
  329.              face->muscle[m]->zone,
  330.              -0.1 ) ;
  331.     glutPostRedisplay();
  332.     break;
  333.  
  334.       case 'b' :
  335.     DRAW_MODE++ ;
  336.  
  337.     if ( DRAW_MODE >= 3 ) DRAW_MODE = 0 ;
  338.     printf ("draw mode: %d\n", DRAW_MODE ) ;
  339.     glutPostRedisplay();
  340.     break;
  341.  
  342.       case 'c' :
  343.     face_reset ( face ) ;
  344.     glutPostRedisplay();
  345.     break;
  346.     
  347.       case 'n' :
  348.     m++ ;
  349.     if ( m >= face->nmuscles ) m = 0 ;
  350.         sprintf(title, "geoface (%s)", face->muscle[m]->name);
  351.         glutSetWindowTitle(title);
  352.     break;
  353.  
  354.       case 'e' :
  355.     if (face->expression) {
  356.     face_reset  ( face ) ;
  357.     expressions ( face, e ) ;
  358.  
  359.     e++ ;
  360.     if ( e >= face->nexpressions ) e = 0 ;
  361.     glutPostRedisplay();
  362.     }
  363.     break;
  364.  
  365.       case 'h' :
  366.     
  367.     print_mesg();
  368.     
  369.     }
  370. }
  371.  
  372. /* ARGSUSED1 */
  373. void
  374. special(int key, int x, int y)
  375. {
  376.   char title[512];
  377.  
  378.   switch(key) {
  379.   case GLUT_KEY_RIGHT:
  380.     m++ ;
  381.     if ( m >= face->nmuscles ) m = 0 ;
  382.     sprintf(title, "geoface (%s)", face->muscle[m]->name);
  383.     glutSetWindowTitle(title);
  384.     break;
  385.   case GLUT_KEY_LEFT:
  386.     m-- ;
  387.     if ( m < 0 ) m = face->nmuscles - 1 ;
  388.     sprintf(title, "geoface (%s)", face->muscle[m]->name);
  389.     glutSetWindowTitle(title);
  390.     break;
  391.   case GLUT_KEY_UP:
  392.     face->muscle[m]->mstat += 0.1 ;
  393.  
  394.     activate_muscle ( face, 
  395.              face->muscle[m]->head, 
  396.              face->muscle[m]->tail, 
  397.              face->muscle[m]->fs,
  398.              face->muscle[m]->fe,
  399.              face->muscle[m]->zone,
  400.              0.1 ) ;
  401.     glutPostRedisplay();
  402.     break;
  403.   case GLUT_KEY_DOWN:
  404.     face->muscle[m]->mstat -= 0.1 ;
  405.  
  406.     activate_muscle ( face, 
  407.              face->muscle[m]->head, 
  408.              face->muscle[m]->tail, 
  409.              face->muscle[m]->fs,
  410.              face->muscle[m]->fe,
  411.              face->muscle[m]->zone,
  412.              -0.1 ) ;
  413.     glutPostRedisplay();
  414.     break;
  415.   }
  416. }
  417.  
  418.  
  419. /* ========================================================================= *
  420.  * print_mesg
  421.  * Written by: Sing Bing Kang (sbk@crl.dec.com)
  422.  * Date: 11/22/96
  423.  * ========================================================================= */
  424. /*
  425. ** Prints out help message
  426. */
  427. void
  428. print_mesg(void)
  429. {
  430. fprintf(stderr,"\n");
  431. fprintf(stderr,"a:       draw mode (to `pull' the current facial muscle)\n");
  432. fprintf(stderr,"A:       draw mode (to `contract' current facial muscle)\n");
  433. fprintf(stderr,"c:       face reset\n");
  434. fprintf(stderr,"n:       next muscle (to select another facial muscle to manipulate)\n");
  435. fprintf(stderr,"e:       next expression\n");
  436. fprintf(stderr,"b:       to change draw mode: wireframe->polygonal patches->smooth surface\n");
  437. fprintf(stderr,"r,R:     reread the expression file (../face-data/expression-vectors.dat)\n         (Note: this resets the expression sequence to the beginning)\n");
  438. fprintf(stderr,"q,Q,Esc: quit\n");
  439. fprintf(stderr,"h:       outputs this message\n");
  440. fprintf(stderr,"\n");
  441. }
  442.  
  443. void
  444. muscle_select(int value)
  445. {
  446.   char title[512];
  447.  
  448.   /* Select muscle. */
  449.   m = value;
  450.   sprintf(title, "geoface (%s)", face->muscle[m]->name);
  451.   glutSetWindowTitle(title);
  452. }
  453.  
  454. void
  455. main_menu_select(int value)
  456. {
  457.   char title[512];
  458.  
  459.   switch(value) {
  460.   case 1:
  461.     face_reset ( face ) ;
  462.     glutPostRedisplay();
  463.     break;
  464.   case 2:
  465.     print_mesg();
  466.     break;
  467.   case 3:
  468.     face->muscle[m]->mstat += 0.25 ;
  469.     activate_muscle ( face, 
  470.       face->muscle[m]->head, 
  471.       face->muscle[m]->tail, 
  472.       face->muscle[m]->fs,
  473.       face->muscle[m]->fe,
  474.       face->muscle[m]->zone,
  475.       +0.25 ) ;
  476.     glutPostRedisplay();
  477.     break;
  478.   case 4:
  479.     face->muscle[m]->mstat -= 0.25 ;
  480.     activate_muscle ( face, 
  481.       face->muscle[m]->head, 
  482.       face->muscle[m]->tail, 
  483.       face->muscle[m]->fs,
  484.       face->muscle[m]->fe,
  485.       face->muscle[m]->zone,
  486.       -0.25 ) ;
  487.     glutPostRedisplay();
  488.     break;
  489.   case 5:
  490.     m++ ;
  491.     if ( m >= face->nmuscles ) m = 0 ;
  492.     sprintf(title, "geoface (%s)", face->muscle[m]->name);
  493.     glutSetWindowTitle(title);
  494.     break;
  495.   case 666:
  496.     exit(0);
  497.     break;
  498.   }
  499. }
  500.  
  501. void
  502. draw_mode_select(int value)
  503. {
  504.   DRAW_MODE = value;
  505.   glutPostRedisplay();
  506. }
  507.  
  508. void
  509. make_menus(void)
  510. {
  511.   int i, j, muscle_menu, draw_mode_menu;
  512.   char *entry;
  513.  
  514.   muscle_menu = glutCreateMenu(muscle_select);
  515.   for (i=0; i<face->nmuscles; i++) {
  516.     entry = face->muscle[i]->name;
  517.     for(j=(int) strlen(entry)-1; j>=0; j--) {
  518.       if (entry[j] == '_') entry[j] = ' ';
  519.     }
  520.     glutAddMenuEntry(entry, i);
  521.   }
  522.   draw_mode_menu = glutCreateMenu(draw_mode_select);
  523.   glutAddMenuEntry("Wireframe", 0);
  524.   glutAddMenuEntry("Polygonal patches", 1);
  525.   glutAddMenuEntry("Smooth surface", 2);
  526.   glutCreateMenu(main_menu_select);
  527.   glutAddMenuEntry("Pull muscle up", 3);
  528.   glutAddMenuEntry("Pull muscle down", 4);
  529.   glutAddMenuEntry("Next muscle", 5);
  530.   glutAddSubMenu("Select muscle", muscle_menu);
  531.   glutAddSubMenu("Draw mode", draw_mode_menu);
  532.   glutAddMenuEntry("Face reset", 1);
  533.   glutAddMenuEntry("Print help", 2);
  534.   glutAddMenuEntry("Quit", 666);
  535.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  536. }
  537.  
  538. /* ========================================================================= */
  539. /* main                                                                */
  540. /* ========================================================================= */
  541. /*
  542. ** All the initialization and action takes place here.
  543. */
  544.  
  545. void main ( int argc, char** argv )
  546. {
  547.   int i;
  548.  
  549.   glutInitWindowSize    ( 400, 600 ) ;
  550.   glutInit(&argc, argv);
  551.   for(i=1; i<argc; i++) {
  552.     if(!strcmp(argv[i], "-v")) {
  553.       verbose = 1;
  554.     }
  555.   }
  556.   glutInitDisplayMode    (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
  557.   glutCreateWindow        ( "geoface" ) ;
  558.   myinit        ( ) ;
  559.   faceinit        ( ) ;
  560.   glutMouseFunc(mouse);
  561.   glutMotionFunc(motion);
  562.   glutKeyboardFunc        ( Key ) ;    
  563.   glutSpecialFunc(special);
  564.   glutReshapeFunc     ( myReshape ) ;
  565.   glutDisplayFunc(display);
  566.   make_menus();
  567.   glutMainLoop() ;
  568. }
  569.  
  570.   
  571.  
  572.